function varargout = fm_threed(varargin)
% FM_THREED create GUI for network visualisations
%
% HDL = FM_THREED()
%
%Author:    Federico Milano
%Date:      21-Aug-2007
%Version:   1.0.0
%
%E-mail:    Federico.Milano@uclm.es
%Web-site:  http://www.uclm.es/area/gsee/Web/Federico
%
% Copyright (C) 2002-2013 Federico Milano

global Settings Theme Varout Path Fig File CPF OPF

% check for data file
if isempty(File.data)
  fm_disp('Set a data file for running sparse matrix visualisation.',2)
  return
end

% check for initial power flow solution
if ~Settings.init
  fm_disp('Solve base case power flow...')
  Settings.show = 0;
  fm_set('lf')
  Settings.show = 1;
  if ~Settings.init, return, end
end

if nargin

  if ~Fig.threed, return, end
  hdl1 = findobj(Fig.threed,'Tag','PopupMenu1');
  hdl2 = findobj(Fig.threed,'Tag','PopupMenu2');
  value1 = get(hdl1,'Value');
  value2 = get(hdl2,'Value');

  switch varargin{1}

   case 'update'
    hdl3 = findobj(Fig.threed,'Tag','MenuCaxis');
    if value2 == 1
      set(hdl3,'Enable','on')
    else
      set(hdl3,'Enable','off')
    end
    if (value2 == 6 || value2 == 7) && ~OPF.init
      fm_disp(['Run OPF before displaying Locational Marginal ' ...
               'Prices'],2)
      set(hdl2,'Value',1)
      set(hdl3,'Enable','on')
      return
    end
    fm_simrep('DrawModel',value1,value2,0)

   case 'init'
    Varout.movie = getframe(findobj(Fig.threed,'Tag','Axes1'));
    hdl = findobj(Fig.threed,'Tag','Axes1');
    togglecontrols(Fig.threed,'off')

   case 'newframe'
    fm_simrep('DrawModel',value1,value2,1)

   case 'finish'
    togglecontrols(Fig.threed,'on')

   case 'movie'
    if isempty(Varout.movie), return, end
    axes(findobj(Fig.threed,'Tag','Axes1'));
    xlabel('')
    %axes('Position',[0 0 1 1])
    if Settings.init > 1 && ~CPF.init
      fps = round(length(Varout.movie)/(Settings.tf-Settings.t0));
      if ~fps, fps = 12; end
      movie(Varout.movie,1,fps)
    else
      movie(Varout.movie)
    end

   case 'savemovie'
    if isempty(Varout.movie), return, end
    cd(Path.data)
    filedata = strrep(File.data,'@ ','');
    filedata = strrep(filedata,'(mdl)','_mdl');
    mov = avifile(filedata);
    mov = addframe(mov,Varout.movie);
    mov = close(mov);
    cd(Path.local)

   case 'openmovie'
    [filename, pathname] = uigetfile('*.avi', 'Pick an AVI-file');
    if ~pathname, return, end
    cd(pathname)
    Varout.movie = aviread(filename);
    cd(Path.local)

   case 'setcaxis'
    switch get(gcbo,'Checked')
     case 'on'
      set(gcbo,'Checked','off')
      Varout.caxis = 0;
     case 'off'
      set(gcbo,'Checked','on')
      Varout.caxis = 1;
    end
    fm_simrep('DrawModel',value1,value2,0)

   case 'printfig'
    togglecontrols(Fig.threed,'off')
    cd(Path.data)
    filedata = strrep(File.data,'@ ','');
    filedata = strrep(filedata,'(mdl)','_mdl');
    print(Fig.threed,'-dpng',filedata)
    cd(Path.local)
    togglecontrols(Fig.threed,'on')

  end

  return

end

if Fig.threed, figure(Fig.threed), return, end

maps = {'jet';'hot';'gray';'bone';'copper';'pink';
  'hsv';'cool';'autumn';'spring';'winter';'summer'};

h0 = figure('Color',Theme.color01, ...
  'Units', 'normalized', ...
  'CreateFcn','Fig.threed = gcf;', ...
  'DeleteFcn','Fig.threed = 0; rotate3d off', ...
  'FileName','fm_threed', ...
  'MenuBar','none', ...
  'Name','Network Visualisation', ...
  'NumberTitle','off', ...
  'PaperPosition',[18 180 576 432], ...
  'PaperUnits','points', ...
  'Position',sizefig(0.666,0.74), ...
  'Resize','on', ...
  'ToolBar','none');

% Menu File
h1 = uimenu('Parent',h0, ...
            'Label','File', ...
            'Tag','MenuFile');
h2 = uimenu('Parent',h1, ...
            'Callback','fm_threed openmovie', ...
            'Label', 'Open movie', ...
            'Tag','OpenMovie', ...
            'Accelerator','o');
h2 = uimenu('Parent',h1, ...
            'Callback','fm_threed savemovie', ...
            'Label', 'Save movie', ...
            'Tag','SaveMovie', ...
            'Accelerator','s');
h2 = uimenu('Parent',h1, ...
            'Callback','fm_threed printfig', ...
            'Label', 'Save frame', ...
            'Tag','PrintFig', ...
            'Accelerator','p');
h2 = uimenu('Parent',h1, ...
            'Callback','close(gcf)', ...
            'Label','Close', ...
            'Tag','FileClose', ...
            'Separator','on', ...
            'Accelerator','q');

% Menu Edit
h1 = uimenu('Parent',h0, ...
            'Label','Edit', ...
            'Tag','MenuEdit');
h2 = uimenu('Parent',h1, ...
            'Callback','fm_threed update', ...
            'Label', 'Update', ...
            'Accelerator','u', ...
            'Tag','MenuUpdate');
h2 = uimenu('Parent',h1, ...
            'Callback','fm_threed movie', ...
            'Label', 'Play movie', ...
            'Accelerator','m', ...
            'Tag','MenuPlay');

% Menu View
h1 = uimenu('Parent',h0, ...
            'Label','View', ...
            'Tag','MenuView');
h2 = uimenu('Parent',h1, ...
            'Callback','fm_threed setcaxis', ...
            'Label', 'Use voltage limits', ...
            'Accelerator','v', ...
            'Tag','MenuCaxis');
if Varout.caxis
  set(h1,'Checked','on')
else
  set(h1,'Checked','off')
end

h2 = uimenu('Parent',h1, ...
            'Label', 'Transparency', ...
            'Tag','MenuTransparency', ...
            'Separator','on');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(1), Varout.alpha = 1;', ...
            'Label','None', ...
            'Tag','alpha1', ...
            'Accelerator','0');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.9), Varout.alpha = 0.9;', ...
            'Label','alpha = 0.9', ...
            'Tag','alpha1', ...
            'Accelerator','9');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.8), Varout.alpha = 0.8;', ...
            'Label','alpha = 0.8', ...
            'Tag','alpha1', ...
            'Accelerator','8');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.7), Varout.alpha = 0.7;', ...
            'Label','alpha = 0.7', ...
            'Tag','alpha1', ...
            'Accelerator','7');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.6), Varout.alpha = 0.6;', ...
            'Label','alpha = 0.6', ...
            'Tag','alpha1', ...
            'Accelerator','6');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.5), Varout.alpha = 0.5;', ...
            'Label','alpha = 0.5', ...
            'Tag','alpha1', ...
            'Accelerator','5');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.4), Varout.alpha = 0.4;', ...
            'Label','alpha = 0.4', ...
            'Tag','alpha1', ...
            'Accelerator','4');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.3), Varout.alpha = 0.3;', ...
            'Label','alpha = 0.3', ...
            'Tag','alpha1', ...
            'Accelerator','3');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.2), Varout.alpha = 0.2;', ...
            'Label','alpha = 0.2', ...
            'Tag','alpha1', ...
            'Accelerator','2');
h3 = uimenu('Parent',h2, ...
            'Callback','alpha(0.1), Varout.alpha = 0.1;', ...
            'Label','alpha = 0.1', ...
            'Tag','alpha1', ...
            'Accelerator','1');

%fm_set colormap

h1 = axes('Parent',h0, ...
  'Box','on', ...
  'CameraUpVector',[0 1 0], ...
  'CameraUpVectorMode','manual', ...
  'Color',Theme.color11, ...
  'Position',[0.09 0.152 0.85 0.779], ...
  'Tag','Axes1', ...
  'XColor',[0 0 0], ...
  'YColor',[0 0 0], ...
  'ZColor',[0 0 0]);

set(h0,'UserData',h1);

h1 = uicontrol('Parent',h0, ...
  'CData',fm_mat('threed_matlab'), ...
  'BackgroundColor',Theme.color02, ...
  'Units', 'normalized', ...
  'Callback','fm_threed update', ...
  'Position',[0.673 0.0185 0.06 0.08], ...
  'TooltipString','Update', ...
  'Tag','Pushbutton1');

h1 = uicontrol('Parent',h0, ...
  'CData',fm_mat('threed_movie'), ...
  'BackgroundColor',Theme.color02, ...
  'Units', 'normalized', ...
  'Callback','fm_threed movie', ...
  'Position',[0.673+0.0650 0.0185 0.06 0.08], ...
  'TooltipString','Play Movie', ...
  'Tag','Pushbutton2');

h1 = uicontrol('Parent',h0, ...
  'BackgroundColor',Theme.color02, ...
  'Units', 'normalized', ...
  'Callback','close(gcf)', ...
  'Position',[0.82 0.044 0.121 0.052], ...
  'String','Close', ...
  'Tag','Pushbutton3');

h1 = uicontrol('Parent',h0, ...
  'Units', 'normalized', ...
  'Callback','String = get(gcbo,''String''); eval([''colormap '',String{get(gcbo,''Value'')}]);', ...
  'BackgroundColor',Theme.color04, ...
  'Position',[0.488 0.041 0.157 0.056], ...
  'String',maps, ...
  'Style','popupmenu', ...
  'Tag','PopupMenu1', ...
  'Value',1);

h1 = uicontrol('Parent',h0, ...
  'Units', 'normalized', ...
  'Callback','fm_threed update', ...
  'BackgroundColor',Theme.color04, ...
  'Position',[0.27 0.041 0.187 0.056], ...
  'String',{'Voltage Magnitudes','Voltage Angles', ...
            'Line Flows','Gen. Rotor Angles', ...
            'Gen. Rotor Speeds','LMPs','NCPs'}, ...
  'Style','popupmenu', ...
  'Tag','PopupMenu2', ...
  'Value',1);

x = 0.02;
y = 0.05;

% Frame and push buttons for axis manipulation
h1 = uicontrol('Parent',h0, ...
  'Units', 'normalized', ...
  'BackgroundColor',Theme.color02, ...
  'ForegroundColor',Theme.color03, ...
  'Position',[0.0726-x  0.0638-y  0.2000  0.0893], ...
  'Style','frame', ...
  'Tag','Frame2');
h1 = uicontrol('Parent',h0, ...
  'CData',fm_mat('mat_rotate'), ...
  'Units', 'normalized', ...
  'BackgroundColor',Theme.color02, ...
  'Callback','rotate3d(gcf), , if(get(gcbo,''Value'')), set(findobj(gcf,''Tag'',''toggle7''),''Value'',0), zoom(gcf,''off''), end', ...
  'Position',[0.0776-x  0.0685-y  0.0600  0.0800], ...
  'TooltipString','Rotate graph', ...
  'Style','togglebutton', ...
  'Tag','toggle5');
h1 = uicontrol('Parent',h0, ...
  'CData',fm_mat('mat_grid'), ...
  'Units', 'normalized', ...
  'BackgroundColor',Theme.color02, ...
  'Callback','grid(get(Fig.threed,''UserData''))', ...
  'Position',[0.1426-x  0.0685-y  0.0600  0.0800], ...
  'TooltipString','Grid', ...
  'Style','togglebutton', ...
  'Tag','toggle6');
h1 = uicontrol('Parent',h0, ...
  'CData',fm_mat('mat_zoomxy'), ...
  'Units', 'normalized', ...
  'BackgroundColor',Theme.color02, ...
  'Callback','zoom, if(get(gcbo,''Value'')), set(findobj(gcf,''Tag'',''toggle5''),''Value'',0), rotate3d(gcf,''off''), end', ...
  'Position',[0.2076-x  0.0685-y  0.0600  0.0800], ...
  'TooltipString','Zoom', ...
  'Style','togglebutton', ...
  'Tag','toggle7');

if nargout > 0, fig = h0; end

function togglecontrols(fig,flag)

hdl(1) = findobj(fig,'Tag','PopupMenu1');
hdl(2) = findobj(fig,'Tag','PopupMenu2');
hdl(3) = findobj(fig,'Tag','Frame2');
hdl(4) = findobj(fig,'Tag','toggle5');
hdl(5) = findobj(fig,'Tag','toggle6');
hdl(6) = findobj(fig,'Tag','toggle7');
hdl(7) = findobj(fig,'Tag','Pushbutton1');
hdl(8) = findobj(fig,'Tag','Pushbutton2');
hdl(9) = findobj(fig,'Tag','Pushbutton3');
set(hdl,'Visible',flag)